package ac.svn.accesscontrol.manager;

import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.HashSet;
import java.util.Set;

import javax.swing.DefaultListModel;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;

import ac.svn.accesscontrol.store.IResources;
import ac.svn.accesscontrol.store.ISVNIdentifier;
import ac.svn.accesscontrol.store.ISVNItem;
import ac.svn.accesscontrol.ui.IUIConstants;
import ac.svn.accesscontrol.ui.UIComponentLibrary;
import ac.svn.accesscontrol.ui.helper.IntellFilter;
import ac.svn.accesscontrol.ui.renderer.SimpleIconRenderer;
import ac.svn.accesscontrol.ui.window.IntellisensePanel;
import ac.svn.accesscontrol.ui.window.IntellisenseWindow;
import ac.svn.accesscontrol.utils.Utility;

public class IntellisenseManager implements 	ISVNIdentifier,
IUIConstants,
IResources
{ 
	public static enum EItemsType
	{
		TYPE_LOACTION,
		TYPE_GROUP,
		TYPE_USER
	}

	private IntellisenseWindow intellisenseWindow;
	private IntellisensePanel  intellisensePanel;
	private JFrame mainWindow;
	private JLabel titleLabel,matchLabel;

	private IntellFilter groupFilter,userFilter,locationFilter;
	private static IntellisenseManager intellisenseManager;
	private JList lstCurrentDspList;
	private ISVNItem lastSelection;
	private EItemsType intelType;
	

	//Set of message to be sent when selection is made on list.
	private Set<String> messageSet = null;


	private IntellisenseManager()
	{
		initComponent();

		groupFilter 	= new IntellFilter(C_INTEL_ITEM_LIST, C_INTEL_ITEM_MODEL_GROUP);
		userFilter 		= new IntellFilter(C_INTEL_ITEM_LIST, C_INTEL_ITEM_MODEL_USER);
		locationFilter 	= new IntellFilter(C_INTEL_ITEM_LIST, C_INTEL_ITEM_MODEL_LOCATION);
		
		matchLabel = intellisensePanel.getStatusLabel();
		registerListener();
	}

	private void initComponent()
	{
		intellisenseWindow = new IntellisenseWindow();
		intellisensePanel = intellisenseWindow.getIntellisensePanel();
		intellisenseWindow.setSize(new Dimension(400,500));

		titleLabel = intellisensePanel.getTitleLabel();
		Font font = new Font(titleLabel.getFont().getFamily() , Font.PLAIN,16);
		titleLabel.setFont(font);
	}


	private void registerListener() 
	{
		if(null != intellisensePanel)
		{
			if(null != intellisensePanel.getTxtSearch())
			{
				intellisensePanel.getTxtSearch().addKeyListener(new KeyAdapter() 
				{
					@Override
					public void keyReleased(KeyEvent ke) 
					{
						if(KeyEvent.VK_DOWN == ke.getKeyCode())
						{
							intellisensePanel.getLstItems().requestFocus();
						}						
						
						String txt = intellisensePanel.getTxtSearch().getText();
						SVNInfoManager  infoManager = SVNInfoManager.getInfoManager();
						
						switch (intelType) {
						case TYPE_GROUP:
							groupFilter.filterList(infoManager.getAllGroups(), txt);
							break;
						case TYPE_USER:
							userFilter.filterList(infoManager.getAllUsers(), txt);
							break;
						case TYPE_LOACTION:
							locationFilter.filterList(infoManager.getAllLocations(), txt);
							break;
						default:
							break;
						}
					}
				});
				//Text listener ends here.

				intellisensePanel.getLstItems().addKeyListener(new KeyAdapter() 
				{
					@Override
					public void keyReleased(KeyEvent ke) 
					{
						if(KeyEvent.VK_ENTER == ke.getKeyCode())
						{
							lastSelection = informSelection();

						}
						else if(KeyEvent.VK_ESCAPE == ke.getKeyCode())
						{
							hideIntellisense();
						}
					}
				});

				intellisensePanel.getTxtSearch().addKeyListener(new KeyAdapter() 
				{
					@Override
					public void keyReleased(KeyEvent ke) 
					{
						if(KeyEvent.VK_ENTER == ke.getKeyCode())
						{
							lastSelection = informSelection();
							hideIntellisense();
						}
						else if(KeyEvent.VK_ESCAPE == ke.getKeyCode())
						{
							hideIntellisense();
						}
					}
				});

				intellisensePanel.getLstItems().addMouseListener(new MouseAdapter(){
					@Override
					public void mouseClicked(MouseEvent me) {
						if(2 == me.getClickCount())
						{
							lastSelection = informSelection();
							intellisenseWindow.setVisible(false);
						}
					}
				});
			}
			else
			{
				System.err.println("Text field in intellisence is not intialized!");
			}
		}		
		
		intellisensePanel.getHelpButton().addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent arg0) {
				String message = "<HTML><p align=\"CENTER\">Intellisense provides a feature of filtering result.<br>" +
						"Wild card search like using '*' is not present so don't mind using them. Yet search is text anywhere!<br>" +
						"Some seemingly irrelavent result may appear in search as search extends to associated information also of the type!<br><br>" +
						"Finally intellisense window disappears after pressing help button and  I know this!</p></HTML>";
				JOptionPane.showMessageDialog(null, message, "Help Topic", JOptionPane.INFORMATION_MESSAGE);
				
			}
		});
	}

	private ISVNItem informSelection()
	{
		ISVNItem isvnItem = (ISVNItem) intellisensePanel.getLstItems().getSelectedValue();
		if(null != messageSet)
		{
			if(null != isvnItem)
			{
				for(String message:messageSet)
				{
					Utility.sendNotification(message, isvnItem);
				}
			}
		}
		return isvnItem;
	}

	public void showIntellisence(Set<String> messageSet,EItemsType itemsType)
	{
		this.intelType = itemsType;
		this.messageSet = null;
		this.messageSet = messageSet;

		String titleText = "";
		
		groupFilter.setFilterResultLabel(null);
		userFilter.setFilterResultLabel(null);
		locationFilter.setFilterResultLabel(null);

		//Populate Items List on the basis of 	
		switch (itemsType) 
		{
		case TYPE_GROUP:
			resetList(LOC_ICN_GROUP_SMALL, C_INTEL_ITEM_MODEL_GROUP);
			groupFilter.filterList(SVNInfoManager.getInfoManager().getAllGroups(), "");
			titleText = "Select a Group!";
			groupFilter.setFilterResultLabel(matchLabel);
			break;
		case TYPE_USER:
			resetList(LOC_ICN_USER_SMALL, C_INTEL_ITEM_MODEL_USER);
			userFilter.filterList(SVNInfoManager.getInfoManager().getAllUsers(), "");
			titleText = "Select a User!";
			userFilter.setFilterResultLabel(matchLabel);
			break;
		case TYPE_LOACTION:
			resetList(LOC_ICN_URL, C_INTEL_ITEM_MODEL_LOCATION);
			locationFilter.filterList(SVNInfoManager.getInfoManager().getAllLocations(), "");
			titleText = "Select a Location!";
			locationFilter.setFilterResultLabel(matchLabel);
			break;
		default:
			return;
		}

		//Show intellisense
		showIntellisence(titleText);
	}

	public void showIntellisence(String messageId,EItemsType itemsType)
	{
		//Create a new message set.
		messageSet = null;
		messageSet = new HashSet<String>();
		messageSet.add(messageId);

		showIntellisence(messageSet,itemsType);
	}

	public ISVNItem showUserIntellisense()
	{
		resetList(LOC_ICN_USER_SMALL, C_INTEL_ITEM_MODEL_USER);
		userFilter.filterList(SVNInfoManager.getInfoManager().getAllUsers(), "");
		return lastSelection;
	}

	public ISVNItem showGroupIntellisense()
	{
		resetList(LOC_ICN_GROUP_SMALL, C_INTEL_ITEM_MODEL_GROUP);
		groupFilter.filterList(SVNInfoManager.getInfoManager().getAllGroups(), "");
		return lastSelection;
	}

	public ISVNItem showLocationIntellisense()
	{
		resetList(LOC_ICN_URL, C_INTEL_ITEM_MODEL_LOCATION);
		locationFilter.filterList(SVNInfoManager.getInfoManager().getAllLocations(), "");
		return lastSelection;
	}

	private void resetList(String iconUrl,String modelId)
	{
		lstCurrentDspList = (JList) UIComponentLibrary.getComponent(C_INTEL_ITEM_LIST);
		lstCurrentDspList.setCellRenderer(new SimpleIconRenderer(iconUrl ));
		DefaultListModel model = (DefaultListModel) UIComponentLibrary.getComponent(modelId);
		lstCurrentDspList.setModel(model);
	}


	public  synchronized void showIntellisence(String title)
	{
		intellisenseWindow.setTitle(title);
		intellisenseWindow.setVisible(true);
		lastSelection = null;
		intellisensePanel.getTxtSearch().requestFocus();
		intellisensePanel.getTxtSearch().setText("");
		//intellisensePanel.repaint();
	}


	public synchronized void hideIntellisense()
	{
		intellisenseWindow.setVisible(false);
	}

	public static IntellisenseManager getIntellisenseManager() 
	{
		if(null == intellisenseManager)
		{
			intellisenseManager = new IntellisenseManager();
		}
		return intellisenseManager;
	}



	public void setMainWindow(JFrame mainWindow) {
		this.mainWindow = mainWindow;
	}



	public JFrame getMainWindow() {
		return mainWindow;
	}


}
